from twisted.internet import reactor, protocol, stdio
from Cache import *
import time
import sys
from twisted.protocols import basic
from sys import stdout
import thread

dispatcher = {}
request = {}
test_sequence = []
test_state = 0
user_seq = 0
	
def Send_UserInfoSyn(client, seq) :
	global user_seq
	req = UserInfoSyn()
	req.seq = seq	
	client.send(req)
	print '============================================================'
	print 'Send_UserInfoSyn'	
	print '============================================================'
	
def Read_UserInfoAck(client, recv_data) :
	global user_seq
	ack = UserInfoAck()
	ack.Load(recv_data)
	print '============================================================'
	print 'Read_UserInfoAck'	
	print '============================================================'
	
	Send_CharInfoSyn(client, user_seq, user_seq-90)

def Send_CharInfoSyn(client, seq, char_seq) :
	global user_seq
	req = CharacterInfoSyn()
	req.seq = seq
	req.char_seq = char_seq	
	client.send(req)
	print '============================================================'
	print 'Send_CharInfoSyn'	
	print '============================================================'
	
def Read_CharInfoAck(client, recv_data) :
	global user_seq
	ack = CharacterInfoAck()
	ack.Load(recv_data)
	print '============================================================'
	print 'Read_CharInfoAck'	
	print '============================================================'
	Send_FlushCharacterInfoSyn(client, user_seq, user_seq-90)
	
	
	
def Send_FlushCharacterInfoSyn(client, seq, char_seq) :
	global user_seq
	charInfo = CharacterInfo();
	req = FlushCharacterInfoSyn()
	req.seq = seq
	req.char_seq = char_seq	
	req.flushDB = True
	req.stCharacterInfo = charInfo;
	client.send(req)
	print '============================================================'
	print 'Send_FlushCharacterInfoSyn'	
	print '============================================================'
	
def Read_FlushCharacterInfoAck(client, recv_data) :
	global user_seq
	print '============================================================'
	print 'Read_FlushCharacterInfoAck'	
	print '============================================================'
	Send_FlushUserInfoSyn(client, user_seq)
	
def Send_FlushUserInfoSyn(client, seq) :
	global user_seq
	
	userInfo = UserInfo();
	userInfo.seq = seq
	userInfo.nickname = 'DDD'
	userInfo.profile_url = "EEE"
		
	req = FlushUserInfoSyn()
	req.seq = seq	
	req.flushDB = True
	req.stUserInfo = userInfo;
	client.send(req)
	print '============================================================'
	print 'Send_FlushUserInfoSyn'	
	print '============================================================'
	
def Read_FlushUserInfoAck(client, recv_data) :
	global user_seq
	print '============================================================'
	print 'Read_FlushUserInfoAck'	
	print '============================================================'
	
	Send_FlushUserSlotInfoSyn(client,user_seq, 1)
	
	
def Send_FlushUserSlotInfoSyn(client, seq, slotIndex) :
	global user_seq
	
	stslot = slot()
	stslot.open = True
	stslot.seq = 2
	stslot.classtype = 2
	stslot.level = 1
	stslot.reg_date = '2013-08-07 00:00:00'
		
	req = FlushUserSlotInfoSyn()
	req.seq = seq	
	req.slotIndex = slotIndex
	req.stSlot = stslot
	
	client.send(req)
	print '============================================================'
	print 'Send_FlushUserSlotInfoSyn'	
	print '============================================================'
	
def Read_FlushUserSlotInfoAck(client, recv_data) :
	global user_seq
	print '============================================================'
	print 'Read_FlushUserSlotInfoAck'	
	print '============================================================'
	
	Send_RemoveUserSyn(client,user_seq)

def Send_RemoveUserSyn(client, seq) :
	req = RemoveUserSyn()
	req.seq = seq	
	client.send(req)
	print '============================================================'
	print 'Send_RemoveUser'	
	print '============================================================'
	
	
def Read_RemoveUserAck(client, recv_data) :
	global user_seq
	print '============================================================'
	print 'Read_RemoveUser'	
	print '============================================================'
	time.sleep(2)
	Send_UserInfoSyn(client, user_seq)
	
	
	
test_sequence.append(Send_UserInfoSyn)
#test_sequence.append(Send_GetUserInfo)

dispatcher[UserInfoAck.MSG_ID] = Read_UserInfoAck
dispatcher[CharacterInfoAck.MSG_ID] = Read_CharInfoAck
dispatcher[FlushCharacterInfoAck.MSG_ID] = Read_FlushCharacterInfoAck
dispatcher[FlushUserInfoAck.MSG_ID] = Read_FlushUserInfoAck
dispatcher[FlushUserSlotInfoAck.MSG_ID] = Read_FlushUserSlotInfoAck
dispatcher[RemoveUserAck.MSG_ID] = Read_RemoveUserAck

def console(threadName, client) :
	while True :
		value = input('msg id :')
		if (value == 501):
			receiver = input('user_seq :')
			Send_UserInfoSyn(client, receiver)
		elif (value == 503):
			user_seq = input('user_seq :')
			char_seq = input('char_seq :')
			Send_CharInfoSyn(client, user_seq, char_seq)
		elif (value == 505):
			user_seq = input('user_seq :')
			char_seq = input('char_seq :')
			Send_FlushCharacterInfoSyn(client, user_seq, char_seq)
		elif (value == 507):
			user_seq = input('user_seq :')
			Send_FlushUserInfoSyn(client, user_seq)
		elif (value == 509):
			user_seq = input('user_seq :')
			slot_seq = input('slot_seq :')
			Send_FlushUserSlotInfoSyn(client, user_seq, slot_seq)
		elif (value == 511):
			user_seq = input('user_seq :')			
			Send_RemoveUser(client, user_seq)

class Client(protocol.Protocol): 
	recv_data = ''	
	def connectionMade(self): 
		global test_sequence, test_state, user_seq		
		#thread.start_new_thread(console, ('AA',self))
		#test_sequence[test_state](self)
		Send_UserInfoSyn(self, user_seq)

	def connectionLost(self, reason): 	
		print "connection lost" 

	def dataReceived(self, data) :
		# length of total(include header) : 4byte
		# tag_idl : 4byre
		# data 
		self.recv_data += data
		while len(self.recv_data) :
			global dispatcher, test_sequence, test_state
			if(len(self.recv_data) < 6) :
				print 'received data size is under \'length size\''
				break
		
			recv_bytes_tobe = int(struct.unpack('h', self.recv_data[1:3])[0]) + 3
			if(len(self.recv_data) < recv_bytes_tobe) :
				print 'received data size is under \'total size\''
				break;

			tag_id = struct.unpack('h', self.recv_data[4:6])[0]; 
			recv_data = self.recv_data[6:recv_bytes_tobe] 
			self.recv_data = self.recv_data[recv_bytes_tobe:]
			#print 'tag_id : ' + str(tag_id)
			test_state += 1
			
			dispatcher[tag_id](self, recv_data)
			#console(self)
			#print 'test_state : ' + str(test_state)
			#if test_state < len(test_sequence) :
				#test_sequence[test_state](self)
			
	def send(self, msg) :
		data = msg.Store()
		send_data  = struct.pack('B', 0xff)
		send_data += struct.pack('h', 3 + len(data))
		send_data += struct.pack('b', 0)
		send_data += struct.pack('h', msg.MSG_ID)
		send_data += data
		self.transport.write(send_data)		

class ClientFactory(protocol.ClientFactory): 
	protocol = Client 
	def clientConnectionFailed(self, connector, reason): 
		print "Connection failed - goodbye!" 
		reactor.stop() 
	def clientConnectionLost(self, connector, reason): 
		print "Connection lost - goodbye!" 
		reactor.stop() # this connects the protocol to a server runing on port 8000 

def main():
	global user_seq	
	user_seq = int(sys.argv[1])

	f = ClientFactory()
	reactor.connectTCP("localhost", 20003, f)
	reactor.run()

if __name__ == '__main__': 
	main() 
